// Copyright (C) 2024 Kumo inc.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//

#pragma once

#include <algorithm>
#include <type_traits>
#include <utility>

namespace deneb {

/// The result of an insertion into a cache.
///
/// This is a semantically nicer alternative to a generic `std::pair`, as is
/// returned by `std::unordered_map` or so. It still has the same static
/// interface as the `std::pair` (with `first` and `second` members), but adds
/// nicer `was_inserted()` and `iterator()` accessors.
///
/// \tparam Iterator The class of the iterator contained in the result.
template <typename Iterator>
struct InsertionResult final {
  using IteratorType = Iterator;

  /// Constructor.
  ///
  /// \param result Whether the result was successful.
  /// \param iterator The iterator pointing to the inserted or updated key.
  InsertionResult(bool result, Iterator iterator)
  : first(result), second(iterator) {
  }

  /// \returns True if the key was newly inserted, false if it was only updated.
  bool was_inserted() const noexcept {
    return first;
  }

  /// \returns The iterator pointing to the inserted or updated key.
  Iterator iterator() const noexcept {
    return second;
  }

  /// \copydoc was_inserted
  explicit operator bool() const noexcept {
    return was_inserted();
  }

  /// Whether the result was successful.
  bool first;

  /// The iterator pointing to the inserted or updated key.
  Iterator second;
};

}  // namespace deneb
